package com.ruoyi.mobile.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.WechatConstants;
import com.ruoyi.common.core.redis.RedisUtils;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.JsonUtil;
import com.ruoyi.mobile.model.bo.TokenBo;
import com.ruoyi.mobile.model.bo.UrlschemeBo;
import com.ruoyi.mobile.model.request.GenerateschemeRequest;
import com.ruoyi.mobile.service.IWechatService;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@Service
public class WechatServiceImpl implements IWechatService {

    private static final Logger logger = LoggerFactory.getLogger(WechatServiceImpl.class);

    @Autowired
    private RedisUtils redisUtils;

    public final String BASE_URI = "https://api.weixin.qq.com";

    private String parseParams(String url, HashMap<String, String> params) {
        HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();
        for (Map.Entry < String, String > entry: params.entrySet()) {
            urlBuilder.addQueryParameter(entry.getKey(), entry.getValue());
        }
        return urlBuilder.build().toString();
    }

    /**
     * 获取微信小程序后端调用接口的access_token
     * @param appid
     * @param secret
     * @return
     */
    @Override
    public TokenBo getToken(String appid, String secret) {
        //先去redis里面查有没有，没有就去请求接口
        TokenBo token = JsonUtil.parseObject(JsonUtil.toJSONString(redisUtils.get(CacheConstants.WECHAT_ACCESS_TOKEN)), TokenBo.class);
        if (token != null) {
            return token;
        }
        //拼接url
        HashMap<String, String> map = new HashMap<String, String>();
        map.put("grant_type","client_credential");
        map.put("appid",appid);
        map.put("secret",secret);
        String url = parseParams(BASE_URI + "/cgi-bin/token", map);

        OkHttpClient okHttpClient = new OkHttpClient(); // 创建OkHttpClient对象
        Request request = new Request.Builder().url(url).build(); // 创建一个请求
        try {
            Response response = okHttpClient.newCall(request).execute(); // 返回实体
            if (response.isSuccessful()) { // 判断是否成功
                String string = response.body().string();
                logger.info("获取微信access_token response: " + string);
                token = JsonUtil.parseObject(string, TokenBo.class);
                if (token == null) {
                    throw new ServiceException("获取微信access_token 失败");
                }
                token.setExpires_in(token.getExpires_in() - 120);//防止过期的时候，redis没即时清理掉这个key
                //将token存入redis
                redisUtils.set(CacheConstants.WECHAT_ACCESS_TOKEN, token, Long.valueOf(String.valueOf(token.getExpires_in())));
                return token;
            }else {
                logger.error("获取微信access_token 失败 : code : " + response.code() + " || message : " + response.message()) ;
                throw new ServiceException("获取微信access_token 失败");
            }
        } catch (JsonProcessingException e) {
            logger.error("获取微信access_token 失败 : json 解析失败");
            throw new ServiceException("获取微信access_token 失败");
        } catch (IOException e) {
            logger.error("获取微信access_token 失败 : " + e.getMessage());
            throw new ServiceException("获取微信access_token 失败");
        }
    }

    /**
     * 获取微信小程序scheme 码
     * @return
     */
    @Override
    public String getUrlscheme() {
        TokenBo tokenBo = getToken(WechatConstants.APPID, WechatConstants.SECRET);
        String token = tokenBo.getAccess_token();
        String url = BASE_URI + "/wxa/generatescheme?access_token=" + token;

        //构建请求body
        GenerateschemeRequest.JumpWxaBean jumpWxaBean = new GenerateschemeRequest.JumpWxaBean();
        jumpWxaBean.setPath("pages/home/index");
        GenerateschemeRequest generateschemeRequest = new GenerateschemeRequest();
        generateschemeRequest.setExpire_type(1);
        generateschemeRequest.setExpire_interval(30);
        generateschemeRequest.setJump_wxa(jumpWxaBean);
        String jsonStr = JsonUtil.toJSONString(generateschemeRequest);
        RequestBody body = RequestBody.create(MediaType.get("application/json; charset=utf-8"), jsonStr);

        OkHttpClient okHttpClient = new OkHttpClient(); // 创建OkHttpClient对象
        Request request = new Request.Builder().url(url).post(body).build();
        try{
            Response response = okHttpClient.newCall(request).execute();
            if (response.isSuccessful()) { // 判断是否成功
                String string = response.body().string();
                logger.info("generatescheme response: " + string);
                UrlschemeBo urlschemeBo = JsonUtil.parseObject(string, UrlschemeBo.class);
                if (urlschemeBo == null) {
                    throw new ServiceException("geturlscheme 失败");
                }
                return urlschemeBo.getOpenlink();
            } else {
                logger.error("获取用户手机号 失败 : code : " + response.code() + " || message : " + response.message());
                throw new ServiceException("geturlscheme 失败");
            }
        } catch (Exception e){
            logger.error("获取用户手机号 失败 : " + e.getMessage());
            throw new ServiceException("geturlscheme 失败");
        }

    }


}
